#include "amever.h"

void *map_init (unsigned int id, const char *mypath, const char *name) {
	FILE *fh;
	struct world_map *me = (struct world_map *)malloc(sizeof(struct world_map));
	if ((fh = fopen(mypath, "r")) == 0	) {
		amelog("Couldn't open map file for reading and quitting, I guess.\n");
		server_shut("Couldn't open map.\n");
	}

	me->map_id = id;
	me->height = MAP_MAX_HEIGHT;
	me->width  = MAP_MAX_WIDTH;
	me->mobs  = chain_setInit(0,0,MAP_MAX_MOBS);
	amelog("My name now is %s\n", name);
	strcpy(me->name, name);

	int x = 0; int y = 0;

	struct world_cell *cell;
	char tmp[128];
	while (fgets(s.buffy, sizeof(s.buffy), fh) && y < MAP_MAX_HEIGHT) {
    if ( s.buffy[0] == 'P' || s.buffy[0] =='p' || s.buffy[0] == 'N' || (s.buffy[0] == 'n' && s.buffy[1] != 'a') ) {
	          if (y == 0)
                 me->width = strlen(s.buffy) - 1;
                 for (x=0;x<me->width;x++) {
                   if ((s.buffy[x] == '\n' || s.buffy[x] == '\r') && y == 0) {
                        me->width--;
                        continue;
                   }

		   cell = (struct world_cell *)malloc(sizeof(struct world_cell));
		   memset(cell, 0, sizeof(struct world_cell));
                   if (s.buffy[x] == 'P' || s.buffy[x] == 'p')
                      cell->passable = 1;
                   else if (s.buffy[x] == 'N' || s.buffy[x] == 'n')
                      cell->passable = 0;
						 else {
							 amelog("Not a P or N found in map's %s pattern... continuing though.\n", name);
                      continue;
						 }

						 cell->X = x;
						 cell->Y = y;
						 cell->objects = 0;
						 cell->wmap = me;
						 me->cells[y][x] = cell;
                }
                memset(s.buffy, 0, 255);
					 y++;
         }
			else if (sscanf(s.buffy, "name:%[a-zA-Z0-9]", tmp) == 1) {
				amelog("Setting name to %s\n", tmp);
				strcpy(me->name, tmp);
			}
			else if (sscanf(s.buffy, "lua(%[a-zA-Z0-9/\\.])", tmp) == 1) {
				if (!s.L)
					amelog("Lua is not there yet (%s trying to lua_dofile(%s)).\n", mypath, tmp);
				else {
					amelog("Calling %s from %s\n", tmp, mypath);
					lua_getglobal(s.L, "map_register");
					lua_pushlightuserdata(s.L, me);
					lua_pushnumber(s.L, id);
					lua_pushstring(s.L, me->name);
					lua_call(s.L, 3, 1);
					lua_setglobal(s.L, "map");
					lua_dofile(s.L, tmp);
				}
			}
 }
/*
	if (y == MAP_MAX_HEIGHT)
		amelog("warning: Max map height reached on %s\n");
*/
	me->height = y;
	amelog("Map %s (%dx%d) successfuly loaded.\n", me->name, me->width, me->height);
	amelog("Map->mobs 0x%x inited.\n", me->mobs);
	fclose(fh);
	return me;

 error:
 	chain_setShut(me->mobs);
 	free(me);
  return 0;
}

void map_shut(struct world_map *me) {
	int y, x;
	amelog("Shutting a %dx%d map.\n", me->width, me->height);

	chain_setShut(me->items);
	chain_setShut(me->chars);
	chain_setShut(me->mobs);

	for (y=0;y<me->height;y++) {
		for (x=0;x<me->width;x++) {
			if (me->cells[y][x]->objects)
				chain_setShut(me->cells[y][x]->objects);
			free(me->cells[y][x]);
		}
	}

	free(me);// Not really correct but oh well...
}

int map_foreach(int type, struct world_cell *cell, int radius, struct chain_set *result) {
	if (!cell) return 0;
	int y, x;
	int x0 = cell->X - radius >= 0 ? cell->X - radius : 0;
	int y0 = cell->Y - radius >= 0 ? cell->Y - radius : 0;
	int x1 = cell->X + radius > cell->wmap->width ? cell->wmap->width : cell->X + radius;
	int y1 = cell->Y + radius > cell->wmap->height ? cell->wmap->height : cell->Y + radius;

	for (y=y0;y<=y1;y++) {
		for (x=x0; x<=x1; x++) {
			struct world_cell *icell = cell->wmap->cells[y][x];
			if (icell && icell->objects && icell->objects->len > 0) {
				struct chain_node *noderator = icell->objects->first;
				while (noderator) {
					if (noderator->index == type) {
						chain_nodeInit(result, noderator->val, type, 0);
					}
					noderator = noderator->next;
				}
			}
		}
	}
	return result->len;
}

void *map_lookup(short int id) {

	return 0;
}
